package com.xunua.webrtcdemo.utils;

import android.text.TextUtils;
import android.util.Log;

import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.webrtc.IceCandidate;

import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

public class WebSecketService {
    private String TAG = "huang=====";

    private static WebSecketService instance;
    private boolean isWebSocket;
    private String wss_url = "wss://guardingeyeai.com/wss";
    private WebSocketClient webSocketClient;
    private Timer timerHeat;
    // 状态：表示未登录，表示登录成功
    private boolean isLogin = false;
    private String device_id;
    private String viewer_id ="";
    private String password;
    private OnWebSecketListern listern;


    // 私有化构造函数，防止外部直接创建实例
    private WebSecketService() {

    }

    // 提供一个静态的公有方法，当使用到该方法时，才去创建instance
    public static synchronized WebSecketService getInstance() {
        if (instance == null) {
            instance = new WebSecketService();
        }
        return instance;
    }

    public void startCreateSocketClient() {
        if (webSocketClient != null && isWebSocket) {
            return;
        }
        isWebSocket = false;
        webSocketClient = new WebSocketClient(URI.create(wss_url)) {
            @Override
            public void onOpen(ServerHandshake handshakedata) {
                isWebSocket = true;
                Log.e(TAG, "WebSocketClient==============已连接");
                Log.e(TAG, "WebSocketClient=============onOpen == Status == " + handshakedata.getHttpStatus() + " StatusMessage == " + handshakedata.getHttpStatusMessage());

                if (WebSecketService.this.listern != null) {
                    WebSecketService.this.listern.onConnected();
                }
                sendLogin();
                startTimeHeat();
            }

            @Override
            public void onMessage(String message) {
                if (!message.contains("heartbeat")) {
                    Log.e(TAG, "WebSocketClient======收到消息====onMessage == " + message);
                }
                WebSecketBean webSecketBean = JsonUtil.json2pojo(message, WebSecketBean.class);
                if ("login_response".equals(webSecketBean.type)) {
                    if (webSecketBean.result == 200) {
                        if (!TextUtils.isEmpty(webSecketBean.viewer_id)) {
                            WebSecketService.this.viewer_id = webSecketBean.viewer_id;
                            isLogin = true;
                        }
                    } else if (webSecketBean.result == 407) {
                        //password is invalid!
                    } else if (webSecketBean.result == 404) {
                        //device doesn't exist!
                    }
                    if (WebSecketService.this.listern != null) {
                        WebSecketService.this.listern.onLoginStatus(webSecketBean.result, WebSecketService.this.viewer_id);
                    }
                } else if ("logout_reponse".equals(webSecketBean.type)) {
                    Log.e(TAG, "WebSocketClient========logout_reponse==退出登录 == ");
                    isLogin = false;
                } else if ("offer".equals(webSecketBean.type)) {
                    Log.e(TAG, "WebSocketClient==========offer =sdp= " + webSecketBean.sdp);
                    if (WebSecketService.this.listern != null) {
                        WebSecketService.this.listern.onReceiveOffer(webSecketBean);
                    }
                } else if ("answer".equals(webSecketBean.type)) {
                    Log.e(TAG, "WebSocketClient==========answer =sdp= " + webSecketBean.sdp);
                    if (WebSecketService.this.listern != null) {
                        WebSecketService.this.listern.onReceiveAnswer(webSecketBean);
                    }
                } else if ("candidate".equals(webSecketBean.type)) {
                    Log.e(TAG, "WebSocketClient==========candidate == ");
                    if (WebSecketService.this.listern != null) {
                        WebSecketService.this.listern.onReceiveCandidate(webSecketBean);
                    }
                } else if ("heartbeat_response".equals(webSecketBean.type)) {
                    //Log.e(TAG, "WebSocketClient==========heartbeat_response===result == " + webSecketBean.result);
                }
            }

            @Override
            public void onClose(int code, String reason, boolean remote) {
                Log.e(TAG, "WebSocketClient==============已关闭");
                Log.e(TAG, "WebSocketClient==============onClose == code " + code + " reason == " + reason + " remote == " + remote);
                isWebSocket = false;
            }

            @Override
            public void onError(Exception ex) {
                Log.e(TAG, "WebSocketClient==============onError == " + ex.getMessage());
                Log.e(TAG, "WebSocketClient==============onError== " + ex.getMessage());
                isWebSocket = false;
            }
        };
        webSocketClient.connect();
    }

    private void startTimeHeat() {
        stopeTimeHeat();
        timerHeat = new Timer();
        timerHeat.schedule(new TimerTask() {
            @Override
            public void run() {
                if (isWebSocket()) {
                    if (!isLogin) {
                        sendLogin();
                    } else {
                        sendHearbeat();
                    }
                }
            }
        }, 1000, 1000);
    }

    public void stopeTimeHeat() {
        if (timerHeat != null) {
            timerHeat.cancel();
        }
    }

    public boolean isWebSocket() {
        return isWebSocket;
    }


    // 发送登入资料
    public void login(String device_id, String password, OnWebSecketListern listern) {
        this.device_id = device_id;
        this.password = password;
        this.listern = listern;
        startCreateSocketClient();
    }

    public void logou() {
        if (isWebSocket()) {
            sendlogou();
        }
        stopeTimeHeat();
        webSocketClient.close();
        webSocketClient = null;
        isWebSocket = false;
    }

    public void sendlogou() {
        Map<String, Object> map = new HashMap<>();
        map.put("type", "logout");
        map.put("device_id", this.device_id);
        map.put("viewer_id", this.viewer_id);
        sendContent(JsonUtil.obj2json(map));
    }

    // 发送登入资料
    public void sendLogin() {
        Map<String, Object> map = new HashMap<>();
        map.put("type", "login");
        map.put("device_id", this.device_id);
        map.put("viewer_id", this.viewer_id);
        map.put("password", this.password);
        map.put("expire_time", 3000);
        map.put("stream_id", this.device_id);
        map.put("request_offer", 1);
        map.put("audio_only", 0);
        sendContent(JsonUtil.obj2json(map));
    }

    // 发送心跳包
    public void sendHearbeat() {
        Map<String, Object> map = new HashMap<>();
        map.put("type", "heartbeat");
        sendContent(JsonUtil.obj2json(map));
    }

    // 发送提供资料
    public void sendOffer(String desc) {
        Map<String, Object> map = new HashMap<>();
        map.put("type", "offer");
        map.put("device_id", this.device_id);
        map.put("viewer_id", this.viewer_id);
        map.put("sdp", desc);
        sendContent(JsonUtil.obj2json(map));
    }

    // 发送回应资料
    public void sendAnswer(String desc) {
        Map<String, Object> map = new HashMap<>();
        map.put("type", "answer");
        map.put("device_id", this.device_id);
        map.put("viewer_id", this.viewer_id);
        map.put("sdp", desc);
        sendContent(JsonUtil.obj2json(map));
    }

    // 发送申请者资料
    public void sendCandidate(WebSecketBean candidate) {
        Map<String, Object> map = new HashMap<>();
        map.put("type", "answer");
        map.put("device_id", this.device_id);
        map.put("viewer_id", this.viewer_id);
        map.put("id", candidate.id);
        map.put("label", candidate.label);
        map.put("sdpMLineIndex", candidate.sdpMLineIndex);
        map.put("candidate", candidate.candidate);
        sendContent(JsonUtil.obj2json(map));
    }


    //发送内容
    public boolean sendContent(String msg) {
        if (!isWebSocket()) {
            startCreateSocketClient();
            return false;
        }
        webSocketClient.send(msg);
        if (!msg.contains("heartbeat")) {
            Log.e(TAG, "WebSocketClient==============sendContent =发送内容: " + msg);
        }
        return true;
    }

    public static interface OnWebSecketListern {
        void onConnected();

        void onLoginStatus(int code, String viewer_id);

        void onReceiveOffer(WebSecketBean webSecketBean);

        void onReceiveAnswer(WebSecketBean webSecketBean);

        void onReceiveCandidate(WebSecketBean webSecketBean);
    }
}
